package com.sinheldrin.musicplayer.writer
{
	import com.sinheldrin.musicplayer.fields.Field;
	import com.sinheldrin.musicplayer.fields.FieldClass;
	import com.sinheldrin.musicplayer.fields.FieldsModel;
	import com.sinheldrin.musicplayer.library.LibraryController;
	import com.sinheldrin.musicplayer.music.Music;
	import com.sinheldrin.musicplayer.music.MusicCollection;
	import com.sinheldrin.musicplayer.music.Playlist;
	import com.sinheldrin.musicplayer.settings.SettingsModel;
	
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;

	public class XmlWriter implements IWriter
	{
		public function XmlWriter()
		{
		}
		
		public function writeLibrary(library:LibraryController, folder:File, filename:String):Boolean
		{
			var xml:XML = <library/>;
			xml.appendChild(musicCollectionToXml(library));
			
			return writeFile(xml, folder, filename);
		}
		
		public function Write (playlist:Playlist):void
		{
			var xml:XML = RootXml ();
			var musicXml:XML = <musics/>;
			xml.appendChild(musicXml);
			
			for each (var music:Music in playlist.musics)
			{
				musicXml.appendChild (musicToXml(music));
			}
			
			var file:File = File.desktopDirectory;
			file = file.resolvePath("test.xml");
			
			var fs:FileStream = new FileStream ();
			fs.open (file, FileMode.WRITE);
			fs.writeUTFBytes(xml.toXMLString ());
			fs.close ();
		}
		
		private function RootXml ():XML
		{
			return <playlist/>;
		}
		
		private function musicCollectionToXml(collection:MusicCollection):XML
		{
			var musicXml:XML = <musics/>;
			
			for each (var music:Music in collection.musics)
			{
				musicXml.appendChild (musicToXml(music));
			}
			
			return musicXml;
		}
		
		private function musicToXml (music:Music):XML
		{
			var xml:XML = <music id={music.id} video_id={music.videoId}/>;
			for each (var field:Field in music.fields)
			{
				xml.appendChild(fieldToXml(field));
			}
			return xml;
		}
		
		private function fieldToXml(field:Field):XML
		{
			return <field classId={field.fieldClass.id} value={field.value} />;
		}
		
		public function writeSettings (settings:SettingsModel, folder:File, filename:String):Boolean
		{
			var xml:XML = <settings/>;
			xml.appendChild(<applicationXPosition>{settings.applicationXPosition}</applicationXPosition>);
			xml.appendChild(<applicationYPosition>{settings.applicationYPosition}</applicationYPosition>);
			
			return writeFile(xml, folder, filename);
		}
		
		public function writeFieldClasses (fieldClasses:FieldsModel, folder:File, filename:String):Boolean
		{
			var xml:XML = <fieldClasses/>;
			xml.appendChild(fieldClassesToXml(fieldClasses));
			
			return writeFile(xml, folder, filename);
		}
		
		private function fieldClassesToXml(fieldClasses:FieldsModel):XML
		{
			var musicXml:XML = <classes/>;
			
			for each (var fieldClass:FieldClass in fieldClasses.classes)
			{
				musicXml.appendChild (fieldClassToXml(fieldClass));
			}
			
			return musicXml;
		}
		
		private function fieldClassToXml (fieldClass:FieldClass):XML
		{
			return <fieldClass id={fieldClass.id} name={fieldClass.name} isDefault={fieldClass.isDefault}/>;
		}
		
		private function writeFile(xml:XML, folder:File, filename:String):Boolean
		{
			var tmpFile:File = folder.resolvePath(filename + ".tmp");
			var file:File = folder.resolvePath(filename);
			var fs:FileStream = new FileStream ();
			try
			{
				fs.open (tmpFile, FileMode.WRITE);
				fs.writeUTFBytes(xml.toXMLString ());
				fs.close ();
				tmpFile.moveTo(file, true);
			}
			catch (error:Error)
			{
				trace (error);
				return false;
			}
			return true;
		}
	}
}